#include "Actor.h"
#include "BodyScaler.h"

NS_B2D_BEGIN
	
B2D_OBJECT_IMPL(Actor, Spatial)

Actor::Actor(void)
	: mRigidBody(nullptr)
	, mPhysicsEnabled(false)
{
}

Actor::~Actor(void)
{
}


void Actor::setPosition(float x, float y)
{
	Spatial::setPosition(x, y);
	updateRigidBodyTransform();
}

void Actor::setRotation(float r)
{
	Spatial::setRotation(r);
	updateRigidBodyTransform();
}

void Actor::setScale(float sx, float sy)
{
	Spatial::setScale(sx, sy);
	if(mRigidBody != nullptr)
	{
		vec2 ds(mScale.x/sx, mScale.y/sy);
		BodyScaler::Scale(*mRigidBody, ds);
	}
}


void Actor::updateTransformFromRigidBody(void)
{
	if(mRigidBody != nullptr && mPhysicsEnabled)
	{
		const auto& p = mRigidBody->GetPosition();
		set(mPosition, p.x, p.y);
		mRotation = mRigidBody->GetAngle();
		markTransformDirty(POSITION | ROTATION);
	}
}

void Actor::updateRigidBodyTransform(void)
{
	if(mRigidBody != nullptr && mPhysicsEnabled)
	{
		mRigidBody->SetTransform(b2Vec2(mPosition.x, mPosition.y), mRotation);
	}
}

void Actor::setPhysicsEnabled(bool enabled)
{
	if(mPhysicsEnabled != enabled)
	{
		mPhysicsEnabled = enabled;
		if(mRigidBody != nullptr)
			mRigidBody->SetActive(enabled);
		updateRigidBodyTransform();
	}
}

void Actor::createRigidBody(const RigidBodyDef& def)
{
	// Destroy previous rigid body
	if(mRigidBody != nullptr) destroyRigidBody();


	b2World* world;
	mRigidBody = RigidBody::createBody(*world, def);
	mRigidBody->SetTransform(b2Vec2(mPosition.x, mPosition.y), mRotation);
	mRigidBody->SetUserData(this);
}

void Actor::destroyRigidBody(void)
{
	b2World* world;
	world->DestroyBody(mRigidBody);
	mRigidBody = nullptr;
}

NS_B2D_END